<template>
  <div class="app-container"
    style="margin-bottom: 15px; display: flex; align-items: center; flex-direction: column; position: relative;">
    <!-- 搜索区域 -->
    <div class="top-fixed-bar">
      <MySearchBar :keyword="keyword" :is-admin="user.role === 'admin'" @search="val => { keyword = val; onSearch() }"
        @clear-search="onClearSearch" @add-site="handleAddSite" @batch-push="handleBatchPush"
        @add-default="handleAddDefaultConfig" @batch-remove="handleBatchRemove" />

      <BatchDialog :visible.sync="batchDialogVisible" :batch-action="batchAction" :batch-input="batchInput"
        :batch-loading="batchLoading" :remove-placeholder="removePlaceholder" :push-placeholder="pushPlaceholder"
        @close="batchDialogVisible = false" @confirm="confirmBatchAction" />

      <add-site-dialog :visible.sync="addSiteDialogVisible" :site="newSite" @close="addSiteDialogVisible = false"
        @confirm="confirmAddSite" />
    </div>

    <DomainTable :list="list" :loading="loading" :index-method="indexMethod" @push="handlePush"
      @viewLogs="handleViewLogs" @addAd="handleAddAd" @dropdown-command="handleDropdownCommand" />

    <select-template v-model="form.templateName" :visible.sync="dialogVisible" :configs-data="configsData"
      @confirm="confirmPush" />

    <!-- 配置弹窗 -->
    <ConfigDialog :visible="showConfigDialog" :config-result="configResult" :config-update-time="configUpdateTime"
      :user-role="user.role" :is-default-config="isDefaultConfig" @close="closeConfigDialog" @copy="copyConfig"
      @changeDefault="changeDefault" @push="RePushConfig" />


    <div class="choose-line">
      <el-checkbox v-model="showTodayOnly">仅显示今天</el-checkbox>
    </div>
    <div class="pagination-container">
      <el-pagination :current-page="page" :page-size="limit" :page-sizes="[15, 30, 60, 100]" :total="total"
        layout="total, sizes, prev, pager, next" background @current-change="handlePageChange"
        @size-change="handleSizeChange" />
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import MySearchBar from './components/mySearchBar.vue'
import BatchDialog from './components/BatchDialog.vue'
import AddSiteDialog from './components/AddSiteDialog.vue'
import DomainTable from './components/DomainTable.vue'
import SelectTemplate from './components/SelectTemplate.vue'
import ConfigDialog from './components/ConfigDialog.vue'
import { getDomainList, addOrRemoveDomain, getDomainConfig, setAdDeployment } from '@/api/request_server'
import { TASK_TAG, DEPLOY_STATUS } from '@/assets/data/constants'
import { configsData } from '@/assets/data/configsdata'
import { buildConfig } from '@/assets/data/configBuilder'

export default {
  name: 'DomainList',
  components: {
    MySearchBar,
    BatchDialog,
    AddSiteDialog,
    DomainTable,
    SelectTemplate,
    ConfigDialog
  },
  data() {
    return {
      user: null,
      list: [],
      page: 1,
      limit: 15,
      total: 0,
      loading: false,
      keyword: '',
      newSite: {
        host: '',
        dirpath: ''
      },
      addSiteDialogVisible: false,
      dialogVisible: false,
      showConfigDialog: false,
      originConfig: '',
      defaultConfig: '',
      configResult: '',
      configUpdateTime: '',
      isDefaultConfig: false,

      batchDialogVisible: false,
      batchInput: '',
      batchLoading: false,
      batchAction: 'remove', // 'remove' 或 'push'
      removePlaceholder: `https://www.site.com/
https://www.site1.com/path1
https://www.site1.com/path2
https://www.site2.com/path2
https://www.site3.com/path3
https://www.site4.com/path4
......`,

      pushPlaceholder: `https://www.site.com/ template1
https://www.site1.com/path1 template2
https://www.site1.com/path2 template3
https://www.site2.com/path2 template4
https://www.site3.com/path3 template5
https://www.site4.com/path4 template6
......`,

      form: {
        templateName: '',
        host: '',
        dirpath: ''
      },
      configsData,

      currentRow: null,
      showTodayOnly: false

    }
  },
  computed: {
    ...mapGetters(['name', 'avatar', 'roles'])
  },
  watch: {
    showTodayOnly() {
      this.page = 1
      this.fetchData()
    }
  },
  created() {
    this.user = {
      name: this.$store.getters.name,
      role: this.$store.getters.roles.join(' | '),
      apipermissions: this.$store.getters.apipermissions
    }
    this.fetchData()
  },
  methods: {
    indexMethod(index) {
      return (this.page - 1) * this.limit + index + 1
    },
    async fetchData() {
      this.loading = true
      try {
        const res = await getDomainList({
          page: this.page,
          pageSize: this.limit,
          keyword: this.keyword.trim(),
          todayOnly: this.showTodayOnly
        })
        if (res.success) {
          this.list = res.list
          this.total = res.total
        } else {
          this.list = []
          this.total = 0
          this.$message.error('获取数据失败')
        }
      } catch (error) {
        this.list = []
        this.total = 0
        this.$message.error('请求出错：' + error.message)
      } finally {
        this.loading = false
      }
    },
    checkPermission(condition) {
      if (!condition) {
        this.$message.warning('该操作无授权')
        return false
      }
      return true
    },

    handleAddSite() {
      if (!this.checkPermission(this.user.apipermissions.originPush)) return

      this.newSite = { host: '', dirpath: '' }
      this.addSiteDialogVisible = true
    },

    parseInputUrl(input) {
      try {
        const [urlPart, template = ''] = input.trim().split(/\s+/) // 支持空格或Tab
        if (!urlPart) return null

        let fixedInput = urlPart.trim()

        if (!/^https?:\/\//.test(fixedInput)) {
          fixedInput = 'https://' + fixedInput
        }

        fixedInput = fixedInput.replace('://.', '://www.')

        const url = new URL(fixedInput)
        const host = url.hostname.startsWith('.') ? 'www' + url.hostname : url.hostname

        // 至少要是二级域名（a.b.com）
        if (host.split('.').length < 3) return null

        const path = url.pathname.replace(/^\/+|\/+$/g, '')

        return { host, dirpath: path, template: template.trim() }
      } catch {
        return null
      }
    },

    handleBatchRemove() {
      if (!this.checkPermission(this.user.apipermissions.batchDestroy)) return
      this.batchInput = ''
      this.batchAction = 'remove'
      this.batchDialogVisible = true
    },
    handleBatchPush() {
      if (!this.checkPermission(this.user.apipermissions.batchPush)) return
      this.batchInput = ''
      this.batchAction = 'push'
      this.batchDialogVisible = true
    },

    handleAddDefaultConfig() {
      if (!this.checkPermission(this.user.apipermissions.defaultconfig)) return
      this.batchInput = ''
      this.batchAction = 'defaultconfig'
      this.batchDialogVisible = true
    },

    async confirmParsedSites(parsedSites, dialogTitle = '解析结果确认', isNeedTemplate = true) {
      const validTemplates = Object.keys(this.configsData || {})

      const htmlList = `
  <div style="max-height: 80vh; overflow-y: auto; padding-right: 8px;">
    ${parsedSites.map(({ host, dirpath, template }, i) => {
        const valid = template ? validTemplates.includes(template) : true
        return `
        <div style="max-width: 100%; word-break: break-all; margin-bottom: 8px;">
          ${parsedSites.length > 1 ? `<b>第 ${i + 1} 项：</b><br/>` : ''}
          域名：<b>${host}</b><br/>
          目录：<b>${dirpath || '-'}</b><br/>
          ${isNeedTemplate
            ? `模板：<b>${template || '-'}</b>${template
              ? valid
                ? ' ✅'
                : ' ❌（模板不存在）'
              : ''
            }<br/>`
            : ''
          }
        </div>
      `
      }).join('<hr style="margin:6px 0;" />')}
  </div>
`

      try {
        await this.$confirm(
          htmlList,
          dialogTitle,
          {
            dangerouslyUseHTMLString: true,
            confirmButtonText: '确认无误',
            cancelButtonText: '取消',
            iconClass: parsedSites.every(p => !p.template || validTemplates.includes(p.template)) ? 'el-icon-success' : 'el-icon-warning'
          }
        )

        if (isNeedTemplate) {
          const hasInvalid = parsedSites.some(p => p.template && !validTemplates.includes(p.template))
          if (hasInvalid) {
            this.$message.error('存在无效模板，已取消操作')
            return false
          }
        }

        return true
      } catch (e) {
        if (e === 'cancel' || e === 'close') {
          this.$message.info('操作已取消')
        }
        return false
      }
    },

    async confirmAddSite() {
      const input = this.newSite.host.trim()
      const manualDir = (this.newSite.dirpath || '').trim()
      const parsed = this.parseInputUrl(input)
      if (!parsed) {
        this.$message.error('请输入域名或完整链接')
        return
      }

      if (manualDir) {
        parsed.dirpath = manualDir.replace(/^\/+|\/+$/g, '')
      }
      const ok = await this.confirmParsedSites([parsed], '创建站点', true)
      if (!ok) return
      const isValid = parsed.template && Object.keys(this.configsData || {}).includes(parsed.template)
      const data = isValid
        ? { ...parsed, tasktag: TASK_TAG.PUSH, status: DEPLOY_STATUS.PENDING }
        : { host: parsed.host, dirpath: parsed.dirpath || '', tasktag: TASK_TAG.NEW, status: -DEPLOY_STATUS.SKIPPED }
      try {
        const res = await this.pushSitesBatch([data])
        if (res.code === 20000) {
          this.$message.success(res.message || '添加成功')
          this.addSiteDialogVisible = false
          this.fetchData()
        } else {
          this.$message.error(res.message || '添加失败')
        }
      } catch (e) {
        this.$message.error('请求出错：' + (e.message || e))
      }
    },

    async pushSitesBatch(sites) {
      const failed = []

      const tasks = sites.map(site => {
        return (async () => {
          try {
            const tasktag = site.tasktag ?? TASK_TAG.PUSH
            const host = site.host
            const dirpath = site.dirpath || ''
            const status = site.status ?? DEPLOY_STATUS.PENDING
            const operator = this.user.name
            const template = site.template || site.templateName || ''
            const data = { host, dirpath, tasktag, status, operator }
            if ([TASK_TAG.NEW, TASK_TAG.PUSH, TASK_TAG.ADD_D_CONFIG].includes(tasktag) && template.trim()) {
              data.template = template
              const config = buildConfig({ host, dirpath, templateName: template })
              data.defaultconfig = config

              if (tasktag === TASK_TAG.NEW || tasktag === TASK_TAG.PUSH) {
                data.config = config
              }
            }
            if (tasktag === TASK_TAG.REPUSH) {
              data.config = site.config
            }
            const res = await addOrRemoveDomain(data)
            if (res.code !== 20000) {
              failed.push(`${site.host}（${res.message || '未知错误'}）`)
            }
          } catch (err) {
            failed.push(`${site.host}（${err.message || '异常错误'}）`)
          }
        })()
      })

      await Promise.all(tasks)

      if (failed.length) {
        this.$message.error(`以下任务请求失败：\n${failed.join('\n')}`)
        return { code: 40000 }
      } else {
        this.$message.success('任务请求已发送')
        return { code: 20000 }
      }
    },

    confirmPush(templateName) {
      this.dialogVisible = false
      this.form.templateName = templateName
      const sites = [{
        host: this.form.host,
        dirpath: this.form.dirpath,
        templateName: this.form.templateName,
        tasktag: TASK_TAG.PUSH,
        status: DEPLOY_STATUS.PRIORITY
      }]
      // 显示配置预览弹窗
      this.pushSitesBatch(sites)
    },

    async handleRemove(row) {
      if (!this.checkPermission(this.user.apipermissions.destroySite)) return
      const site = { host: row.host, dirpath: row.dirpath || '', tasktag: TASK_TAG.DESTROY, status: DEPLOY_STATUS.PRIORITY }
      const ok = await this.confirmParsedSites([site], `移除信息`, false)
      if (!ok) return
      this.pushSitesBatch([site])
    },
    async confirmBatchAction({ input, onlyChangeTemplate }) {
      console.log(input, onlyChangeTemplate)
      const lines = input
        .split('\n')
        .map(line => line.trim())
        .filter(line => line)

      const sites = lines.map(line => this.parseInputUrl(line)).filter(Boolean)

      if (sites.length === 0) {
        this.$message.warning('未能解析任何有效数据')
        return
      }

      const titleMap = {
        remove: '批量移除',
        defaultconfig: '生成默认配置',
        push: '批量推送'
      }

      const ok = await this.confirmParsedSites(sites, titleMap[this.batchAction] || '批量操作')
      if (!ok) return

      this.batchLoading = true

      try {
        let simplifiedSites

        if (this.batchAction === 'remove') {
          // 批量移除
          simplifiedSites = sites.map(({ host, dirpath, template }) => ({
            host,
            dirpath,
            template,
            tasktag: TASK_TAG.DESTROY,
            status: DEPLOY_STATUS.PRIORITY
          }))
        } else {
          simplifiedSites = sites.map(({ host, dirpath, template }) => {
            const defaultconfig = buildConfig({ host, dirpath, templateName: template })
            let status;
            if (this.batchAction === 'push' && onlyChangeTemplate === true) {
              status = DEPLOY_STATUS.CANCELED
            } else if (this.batchAction === 'defaultconfig') {
              status = DEPLOY_STATUS.DONE
            } else {
              status = DEPLOY_STATUS.PENDING
            }

            return {
              host,
              dirpath,
              template,
              tasktag: this.batchAction === 'defaultconfig' ? TASK_TAG.ADD_D_CONFIG : TASK_TAG.PUSH,
              status,
              defaultconfig
            }
          })
        }
        await this.pushSitesBatch(simplifiedSites)
        this.batchDialogVisible = false
        this.fetchData()
      } catch (err) {
        this.$message.error(`请求失败：${err.message || err}`)
      } finally {
        this.batchLoading = false
      }
    },

    handlePageChange(newPage) {
      this.page = newPage
      this.fetchData()
    },
    handleSizeChange(newSize) {
      this.limit = newSize
      this.page = 1
      this.fetchData()
    },
    onSearch(val) {
      if (val !== undefined) this.keyword = val
      this.keyword = this.keyword.replace(/^https?:\/\//, '').replace(/\/$/, '')
      this.page = 1
      this.fetchData()
    },
    onClearSearch() {
      if (this.keyword.trim() === '') {
        this.page = 1
        this.fetchData()
      }
    },

    handlePush(row) {
      if (!this.checkPermission(this.user.apipermissions.originPush)) return
      this.currentRow = row
      this.form.host = row.host
      this.form.dirpath = row.dirpath || ''
      this.dialogVisible = true
    },

    copyConfig() {
      navigator.clipboard.writeText(this.configResult).then(() => {
        this.$message.success('复制成功！')
      }).catch(() => {
        this.$message.error('复制失败，请手动复制')
      })
    },

    // 弹窗关闭重置表单
    resetDialog() {
      this.form.templateName = Object.keys(this.configsData)[0]
      this.configResult = ''
      this.currentRow = null
    },

    async handleDropdownCommand({ cmd, row }) {
      switch (cmd) {
        case 'viewConfig':
          await this.handleViewConfig(row)
          break
        case 'addHeader':
          await this.AddHeader(row)
          break
        case 'restoreAdTags':
          await this.pushAdDeployment(row, TASK_TAG.CANCELED_D_CONFIG)
          break
        case 'removeAdTags':
          await this.pushAdDeployment(row, TASK_TAG.USED_D_CONFIG)
          break
        case 'remove':
          this.handleRemove(row)
          break
      }
    },

    async pushAdDeployment(row, tasktag) {
      try {
        const confirmed = await this.$confirm(
          `确认要${tasktag === TASK_TAG.USED_D_CONFIG ? '移除' : '恢复'}广告部署吗？`,
          '确认操作',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }
        )
        if (confirmed) {
          await setAdDeployment({
            host: row.host,
            dirpath: row.dirpath,
            operator: this.user.name,
            tasktag,
            status: DEPLOY_STATUS.PENDING
          })
          this.$message.success('已提交部署任务')
        }
      } catch (err) {
        if (err?.response?.data?.code === 40000) {
          this.$message.error('无权操作，请联系Crf')
        }
      }
    },

    async handleViewConfig(row) {
      try {
        const { host, dirpath } = row;
        this.newSite = { host, dirpath };
        const res = await getDomainConfig({ host, dirpath });

        if (res.code !== 20000 || !res.data) {
          this.$message.error(res.data?.message || '获取配置失败');
          return;
        }

        const { config, defaultconfig, finishedTimes, tasktag, status } = res.data;

        this.originConfig = config;
        this.defaultConfig = defaultconfig;
        this.configUpdateTime = finishedTimes;

        this.isDefaultConfig = (tasktag === TASK_TAG.USED_D_CONFIG && status !== DEPLOY_STATUS.CANCELED);
        this.configResult = this.isDefaultConfig ? defaultconfig : config;

        this.showConfigDialog = true;
        this.$message.success('配置获取成功');
      } catch (err) {
        console.error('获取配置异常', err);
        this.$message.error('网络异常，获取配置失败');
      }
    }
    ,
    async changeDefault() {
      this.isDefaultConfig = !this.isDefaultConfig;
      this.configResult = this.isDefaultConfig ? this.defaultConfig : this.originConfig;
    },

    async AddHeader(row) {
      if (!this.checkPermission(this.user.apipermissions.addHeader)) return
      this.$message.success('添加header')
    },

    async RePushConfig(newConfig) {
      this.configResult = newConfig
      const data = { host: this.newSite.host, dirpath: this.newSite.dirpath, config: newConfig, tasktag: TASK_TAG.REPUSH, status: DEPLOY_STATUS.PRIORITY }
      const res = await this.pushSitesBatch([data])
      if (res.code === 20000) {
        this.$message.success(res.message || '添加成功')
        this.addSiteDialogVisible = false
        this.fetchData()
      } else {
        this.$message.error(res.message || '添加失败')
      }
    },
    closeConfigDialog() {
      this.newSite = { host: '', dirpath: '' }
      this.showConfigDialog = false
    },
    handleViewLogs(row) {
      if (!this.checkPermission(this.user.apipermissions.viewLogs)) return
      this.$router.push({
        path: '/deploylogs',
        query: {
          host: row.host,
          dirpath: row.dirpath || ''
        }
      })
    },
    handleAddAd(row) {
      if (!this.checkPermission(this.user.apipermissions.addAd)) return
      this.$router.push({
        path: 'buildconfigs/autoAd',
        query: {
          host: row.host,
          dirpath: row.dirpath || '',
          template: row.template || ''
        }
      })
    }
  }
}
</script>

<style>
.top-fixed-bar {
  width: 100%;
  background-color: #fff;
  padding: 10px 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  justify-content: center;
}

.choose-line {
  margin-top: 15px;
}

.pagination-container {
  max-width: 100%;
  overflow-x: auto;
  margin: 15px 0;
}

.el-message-box {
  width: 90%;
  max-width: 400px;
  margin: auto;
}
</style>
